home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / PCTV3N5 / NEWDEBUG.CXX < prev    next >
C/C++ Source or Header  |  1992-09-29  |  5KB  |  201 lines

  1. /////////////////////////////////////////////////
  2. //  DEBUG DYNAMIC MEMORY ALLOCATION 
  3. //      newdebug.cxx
  4. //
  5. //      Implements a debugging replacement for 
  6. //      the standard C++ memory allocation 
  7. //      operators.
  8. //
  9. //      Tested with:
  10. //          Microsoft C/C++ 7.00
  11. //          Borland C++ 3.x
  12. //
  13. //      Copyright 1992 Scott Robert Ladd
  14. //      All Rights Reserved
  15. /////////////////////////////////////////////////
  16.  
  17. #include "newdebug.h"
  18. #include "stdlib.h"
  19.  
  20. //-----------------------
  21. // static initializations
  22. //-----------------------
  23.  
  24. long NewDbg::Count = 0;
  25. long NewDbg::Bytes = 0;
  26.  
  27. void (* NewDbg::ErrorFunc)(NewDbg::Errors flag)
  28.     = NULL;
  29.  
  30. NewDbg::Errors NewDbg::ErrorFlag 
  31.     = EF_OKAY;
  32.  
  33. const unsigned short NewDbg::CorrectMark 
  34.     = 0x1701;
  35.  
  36. //----------------------------
  37. // NewDbg member functions
  38. //----------------------------
  39.  
  40. int NewDbg::IsDynamic(void * ptr)
  41.     {
  42.     // get pointer to header data
  43.     AllocHeader * trueptr = (AllocHeader *)ptr;
  44.  
  45.     --trueptr;
  46.  
  47.     // return non-zero if marker is correct
  48.     return (trueptr->Marker == CorrectMark);
  49.     }
  50.  
  51. long NewDbg::GetCount()
  52.     {
  53.     return Count;
  54.     }
  55.  
  56. long NewDbg::GetBytes()
  57.     {
  58.     return Bytes;
  59.     }
  60.  
  61. NewDbg::Errors NewDbg::GetError()
  62.     {
  63.     return ErrorFlag;
  64.     }
  65.  
  66. void NewDbg::ClearError()
  67.     {
  68.     ErrorFlag = NewDbg::EF_OKAY;
  69.     }
  70.  
  71. void NewDbg::InstallHandler
  72.                      (void (* func)(Errors flag))
  73.     {
  74.     ErrorFunc = func;
  75.     }
  76.  
  77. void NewDbg::ReportError(Errors err)
  78.     {
  79.     // set current error code
  80.     ErrorFlag = err;
  81.  
  82.     // if a handler function is assigned, call it
  83.     if (ErrorFunc != NULL)
  84.         ErrorFunc(ErrorFlag);
  85.     }
  86.  
  87. //--------------------------------------
  88. // new_handler, operators new and delete
  89. //--------------------------------------
  90.  
  91. void (* _new_handler)() = NULL;
  92.  
  93. void (* set_new_handler(void (* handler)()))()
  94.     {
  95.     // save current pointer for return
  96.     void (* result)() = _new_handler;
  97.  
  98.     // assign user function to _new_handler
  99.     _new_handler = handler;
  100.  
  101.     return result;
  102.     }
  103.  
  104. void * operator new (size_t size)
  105.     {
  106.     // if there's an error, don't allocate
  107.     if (NewDbg::ErrorFlag != NewDbg::EF_OKAY)
  108.         return NULL;
  109.  
  110.     // catch attempts to allocate zero bytes
  111.     if (size == 0u)
  112.         {
  113.         NewDbg::ReportError(NewDbg::EF_ZEROSIZE);
  114.         return NULL;
  115.         }
  116.  
  117.     // calculate size of allocation plus header
  118.     size_t actualsize = 
  119.               size + sizeof(NewDbg::AllocHeader);
  120.  
  121.     // call malloc to allocate memory
  122.     NewDbg::AllocHeader * temp = 
  123.        (NewDbg::AllocHeader *)malloc(actualsize);
  124.  
  125.     // a NULL pointer indicates allocation failure
  126.     if (temp == NULL)
  127.         {
  128.         // report that allocation failed
  129.         NewDbg::ReportError(NewDbg::EF_NOTALLOC);
  130.  
  131.         // call _new_handler if it isn't NULL
  132.         if (_new_handler != NULL)
  133.             _new_handler();
  134.  
  135.         return NULL;
  136.         }
  137.  
  138.     // set values in header
  139.     temp->Marker = NewDbg::CorrectMark;
  140.     temp->Bytes = size;
  141.     
  142.     // increment tracking variables
  143.     ++NewDbg::Count;
  144.     NewDbg::Bytes += size;
  145.  
  146.     // set temp to actual data (past header)
  147.     temp++;
  148.  
  149.     return temp;
  150.     }
  151.  
  152. void operator delete (void * ptr)
  153.     {
  154.     // if there's an error, don't allocate
  155.     if (NewDbg::ErrorFlag != NewDbg::EF_OKAY)
  156.         return;
  157.  
  158.     // get pointer to beginning of data
  159.     NewDbg::AllocHeader * trueptr = 
  160.                       (NewDbg::AllocHeader *)ptr;
  161.  
  162.     // back up to start of header
  163.     --trueptr;
  164.  
  165.     // verify that this IS an allocated pointer
  166.     if (trueptr->Marker != NewDbg::CorrectMark)
  167.         NewDbg::ReportError(NewDbg::EF_INVALID);
  168.     else
  169.         {
  170.         // reverse the bit in the maker so this
  171.         // block cannot be deleted again
  172.         trueptr->Marker = ~NewDbg::CorrectMark;
  173.  
  174.         // reduce total bytes allocated by size
  175.         // of this block
  176.         NewDbg::Bytes -= trueptr->Bytes;
  177.  
  178.         // if the number of bytes allocated is 
  179.         // less than 0, something went wrong
  180.         if (NewDbg::Bytes < 0)
  181.             NewDbg::ReportError(
  182.                            NewDbg::EF_UNDERFLOW);
  183.         else
  184.             {
  185.             // if the count equals zero, too
  186.             // many deletions have occurred
  187.             if (NewDbg::Count == 0)
  188.                 NewDbg::ReportError(
  189.                              NewDbg::EF_TOOMANY);
  190.             else
  191.                 {
  192.                 // decrement number of allocations
  193.                 --NewDbg::Count;
  194.  
  195.                 // free the pointer
  196.                 free(trueptr);
  197.                 }
  198.             }
  199.         }
  200.     }
  201.